package com.ruoyi.promote.service.Impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.promote.domain.entity.TsKsFile;
import com.ruoyi.promote.domain.param.ParamTsKsFileAdd;
import com.ruoyi.promote.domain.param.ParamTsKsFileSel;
import com.ruoyi.promote.mapper.TsKsFileMapper;
import com.ruoyi.promote.service.TsKsFileService;
import com.ruoyi.xuexiao.domain.entity.KsJbxxhz;
import com.ruoyi.xuexiao.mapper.KsJbxxhzMapper;
import io.netty.util.internal.StringUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 矿山文件-业务层实现
 *
 * @author Gzq
 * @since 2024-06-05 15:19:20
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class TsKsFileImpl extends ServiceImpl<TsKsFileMapper, TsKsFile> implements TsKsFileService {
    @Value("${minefile.uploaddirdisc}")
    private String filePath;

    @Value("${minefile.prexypathaccess}")
    private String imgUrl;

    /**
     * 矿山基本信息汇总
     */
    private final KsJbxxhzMapper ksJbxxhzMapper;

    /**
     * 矿山文件持久层
     */
    private final TsKsFileMapper tsKsFileMapper;

    public TsKsFileImpl(KsJbxxhzMapper ksJbxxhzMapper, TsKsFileMapper tsKsFileMapper) {
        this.ksJbxxhzMapper = ksJbxxhzMapper;
        this.tsKsFileMapper = tsKsFileMapper;
    }


    /**
     * 获取矿山文件-条件-分页
     *
     * @author Gzq
     * @since 2024年6月5日15:32:07
     */
    @Override
    public List<TsKsFile> selKsFile(ParamTsKsFileSel paramTsKsFileSel) {
        /*
         * 处理Xkzs为空的情况，则返回所有数据（带有分页）
         * 如果不为空，则继续执行查询操作
         * 查询后将TsKsFile对象列表转换为ResponseTsKsFile对象列表并返回
         * */
        //构建查询条件
        List<TsKsFile> tsKsFiles = tsKsFileMapper.selectList(Wrappers.<TsKsFile>lambdaQuery()
                //获取getXkzh不为null的参数
                .eq(!StringUtil.isNullOrEmpty(paramTsKsFileSel.getXkzh()), TsKsFile::getXkzh, paramTsKsFileSel.getXkzh())
        );
        //映射响应类并且返回
        return tsKsFiles;
    }

    /**
     * 新增矿山文件
     *
     * @param paramTsKsFileAdd 包含上传文件的参数对象
     * @param request       HTTP请求对象，用于构建文件访问URL
     * @return 上传文件的访问URL
     * @throws IOException 如果文件上传或写入过程中发生IO异常
     * @author Gzq
     * @since 2024-06-05 20:04:36
     */
    @Override
    public String jgUploadFile(ParamTsKsFileAdd paramTsKsFileAdd, HttpServletRequest request) throws IOException {
        // 格式化日期用于以下创建本地存储路径
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd");
        // 获取上传的文件
        MultipartFile file = paramTsKsFileAdd.getFile();
        // 格式化当前日期和时间用于拼接新的url路径
        String div = simpleDateFormat.format(new Date());
        // 获取文件扩展名校验是否符合上传规格
        String extension = FileUploadUtils.getExtension(file);
        // 创建一个表示目录路径的File对象并以格式化当前日期和时间创建存储路径
        File pathName = new File(filePath + "/" + div);
        // 检查目录是否不存在，不存在则创建目录及其必要的父目录
        if (!pathName.exists()) {
            pathName.mkdirs();
        }
        // 打印图像保存的位置
        System.out.println("图片上传，保存位置：" + filePath + div);
        String url = null; // 用于保存URL的变量
        // 根据获取的后缀明和允许上传的文件扩展名数组进行判断对比
        String[] allowedExtensions = new String[]{".pdf", ".jpeg", ".jpg", ".png"};
        boolean extensionAllowed = false; // 用于标记是否允许上传的标志
        // 遍历允许上传的文件扩展名数组，检查文件扩展名是否匹配
        String flag = null;
        //循环运行上传的数组后缀
        for (String suffix : allowedExtensions) {
            if (("." + extension).equalsIgnoreCase(suffix)) {
                extensionAllowed = true;
                flag = "." + extension;
                break;
            }
        }

        //根据许可证好查询出对应数据获取后用于拼接访问路径
        KsJbxxhz existingRecord = ksJbxxhzMapper.selectOne(
                Wrappers.lambdaQuery(KsJbxxhz.class)
                        .eq(!StringUtil.isNullOrEmpty(paramTsKsFileAdd.getXkzh()), KsJbxxhz::getXkzh, paramTsKsFileAdd.getXkzh())//许可证号
        );
        File destinationFile = null;
        String kyqr = null;
        if (!flag.equals(".pdf")) {
            // 获取文件扩展名
            extension = FileUploadUtils.getExtension(file);
            // 创建一个表示目录路径的File对象
            pathName = new File(filePath + "/");
            // 检查目录是否不存在，不存在则创建目录及其必要的父目录
            if (!pathName.exists()) {
                pathName.mkdirs();
            }
            // 生成一个唯一的文件名
            String uniqueFileName = UUID.randomUUID().toString().replace("-", "");
            kyqr = existingRecord.getKyqr() + "_" + uniqueFileName + "." + extension;
            // 创建一个表示文件路径的File对象
            //A:/file/yyy-MM-ddXXX公公司（盘路径）
            destinationFile = new File(filePath + kyqr);
            // 将文件传输到指定位置
            file.transferTo(destinationFile);
            url = imgUrl + kyqr;
        } else {
            // 生成一个唯一的文件名
            String uniqueFileName = UUID.randomUUID().toString().replace("-", "");
            kyqr = existingRecord.getKyqr() + "_" + uniqueFileName + "." + extension;
            // 创建一个表示文件路径的File对象
            //A:/file/yyy-MM-ddXXX公公司（盘路径）
            destinationFile = new File(filePath + "/" + div + "/" + kyqr);
            // 将文件传输到指定位置
            file.transferTo(destinationFile);
            // 构造上传文件的URL
            url = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + "/image/" + div + "/" + kyqr;
        }
        //如果数据不存在则抛出异常
       /* if (existingRecord == null) {
            throw new RuntimeException("上传数据丢失从新上传或联系管理员");
        }*/
        Optional<KsJbxxhz> existingRecordOptional = Optional.ofNullable(existingRecord);
        existingRecordOptional.orElseThrow(() -> new RuntimeException("上传数据丢失从新上传或联系管理员"));
        //注入数据信息
        injection(paramTsKsFileAdd, extensionAllowed, file, existingRecord, url, destinationFile, extension);
        return url;
    }

    /**
     * 数据注入
     *
     * @param paramTsKsFileAdd 包含上传文件的参数对象
     *                      existingRecord 查询到的许可证号对应的数据
     *                      url 上传文件的访问URL
     *                      destinationFile 文件传输到的目标文件
     *                      extension 文件扩展名
     *                      file 上传的文件
     *                      extensionAllowed 是否允许上传的标志
     *                      existingRecord 查询到的许可证号对应的数据
     *                      url 上传文件的访问URL
     *                      destinationFile 文件传输到的目标文件
     *                      extension 文件扩展名
     *                      file 上传的文件
     * @author Gzq
     * @since 2024-06-05 20:04:36
     */
    private void injection(ParamTsKsFileAdd paramTsKsFileAdd, boolean extensionAllowed, MultipartFile file, KsJbxxhz existingRecord, String url, File destinationFile, String extension) {
        if (extensionAllowed) {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            LoginUser principal = (LoginUser) authentication.getPrincipal();
            // 获取上传文件的原始文件名
            String originalFileName = file.getOriginalFilename();
            TsKsFile tsKsFilee = new TsKsFile();
            //注入许可证号
            tsKsFilee.setXkzh(existingRecord.getXkzh());
            //注入相对路径
            tsKsFilee.setXdlj(url);
            //注入绝对路径
            tsKsFilee.setJdlj(String.valueOf(destinationFile));
            //注入后缀名称
            tsKsFilee.setWjlx(extension);
            //注入文件大小
            tsKsFilee.setWjdx(file.getSize() / 1024 + "KB");
            //注入当前上传人
            tsKsFilee.setScr(principal.getUserId());
            //注入上传时间
            tsKsFilee.setScsj(new Date());
            //注入文件名称
            tsKsFilee.setWjmc(originalFileName);
            //注入下发日期
            tsKsFilee.setXfrq(paramTsKsFileAdd.getXfrq());
            //注入初室标识
            tsKsFilee.setCsbs(paramTsKsFileAdd.getCsbs());
            //ksFile.setXdlj("/image/" + div +"/"+ kyqr);//相对路径
            tsKsFileMapper.insert(tsKsFilee);
        }
    }
}
